package ewgenius.xube.engine.graphics;

import java.awt.Font;
import java.awt.FontFormatException;
import java.io.IOException;
import java.io.InputStream;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.*;
import org.lwjgl.util.Color;
import org.lwjgl.util.vector.*;
import org.newdawn.slick.TrueTypeFont;
import org.newdawn.slick.util.ResourceLoader;

import static org.lwjgl.opengl.GL11.*;

import ewgenius.xube.XubeEngine;
import ewgenius.xube.engine.Settings;

public class Render {
	protected int framerate = 60;
	protected int screenWidth = 800;
	protected int screenHeight = 600;
	protected Camera camera;
	protected TrueTypeFont font;

	public void initialize(Settings settings) {

		screenWidth = settings.screenWidth;
		screenHeight = settings.screenHeight;

		try {

			DisplayMode displayMode = new DisplayMode(screenWidth, screenHeight);
			if (settings.fullscreen) {
				displayMode = Display.getDesktopDisplayMode();
				Display.setDisplayModeAndFullscreen(displayMode);
			} else
				Display.setDisplayMode(displayMode);

			framerate = settings.framerate;

			Display.setVSyncEnabled(settings.vsync);
			Display.setTitle(settings.title);

			Display.create();

			if (!GLContext.getCapabilities().OpenGL11) {
				System.err
						.println("Your OpenGL version doesn't support the required functionality.");
				Display.destroy();
				System.exit(1);
			}

			initGL();
			//initFonts();

			camera = new Camera(settings);
			camera.initialize();
			camera.update();

		} catch (LWJGLException e) {
			e.printStackTrace();
		}
	}

	protected void initGL() {
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);

		
		GL11.glEnable(GL11.GL_TEXTURE_2D);
		GL11.glShadeModel(GL11.GL_SMOOTH);
		GL11.glDisable(GL11.GL_DEPTH_TEST);
		GL11.glDisable(GL11.GL_LIGHTING);

		GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		GL11.glClearDepth(1);

		//GL11.glEnable(GL11.GL_BLEND);
		//GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);

		GL11.glViewport(0, 0, screenWidth, screenHeight);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);

		GL11.glMatrixMode(GL11.GL_PROJECTION);
		GL11.glLoadIdentity();
		GL11.glOrtho(0, screenWidth, screenHeight, 0, 1, -1);
		GL11.glMatrixMode(GL11.GL_MODELVIEW);
	}

	public void initFonts() {
		Font awtFont = new Font("Times New Roman", Font.BOLD, 24);
		font = new TrueTypeFont(awtFont, true);

		// InputStream inputStream = ResourceLoader
		// .getResourceAsStream("/res/fonts/cubic.ttf");
	}

	public void destroy() {
		Display.destroy();
	}

	public void updateCamera(Vector3f position, Vector3f rotation) {
		camera.setPosition(position.x, position.y, position.z);
		camera.setRotation(rotation.x, rotation.y, rotation.z);
		camera.update();
	}

	public void begin() {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	}

	public void end() {
		Display.update();
		Display.sync(framerate);
	}

	// 2D render section

	public void begin2DRender() {
		glMatrixMode(GL11.GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0, screenWidth, screenHeight, 0, 1, -1);
		glMatrixMode(GL11.GL_MODELVIEW);
	}

	public void end2DRender() {
		glMatrixMode(GL11.GL_PROJECTION);
		glLoadIdentity();
	}

	public void draw2DRect(Vector2f location, int width, int height, Color color) {
		glColor3f(color.getRed() / 255f, color.getGreen() / 255f,
				color.getBlue() / 255f);
		glBegin(GL11.GL_QUADS);
		glVertex2f(location.x, screenHeight - (location.y + height));
		glVertex2f(location.x + width, screenHeight - (location.y + height));
		glVertex2f(location.x + width, screenHeight - (location.y));
		glVertex2f(location.x, screenHeight - (location.y));
		glEnd();
	}

	public void draw2DString(String string, int x, int y) {
		if (font != null) {
			glDisable(GL_CULL_FACE);
			org.newdawn.slick.Color.red.bind();
			font.drawString(x, y, string);
			glEnable(GL_CULL_FACE);
		}
	}

	// 3d render section

	public void beginModelRender(Vector3f position, Vector3f rotation) {
		glPushMatrix();
		glTranslatef(position.x, position.y, position.z);
		glRotatef(rotation.x, 1, 0, 0);
		glRotatef(rotation.y, 0, 1, 0);
		glRotatef(rotation.z, 0, 0, 1);
		glTranslatef(-position.x, -position.y, -position.z);
	}

	public void endModelRender() {
		glEnd();
		glFlush();
		glPopMatrix();
	}
}
